﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows.Forms;
using System.Windows.Input;
using Core;
using Core.ImageUtil;
using Core.Logger;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;

namespace WP2BE.ViewModel
{
    public class PostOptionViewModel: ViewModelBase
    {
        private string _wpFileName;
        private bool _saveButtonClicked;
        private int _postImagesTotalCount;
        private int _postImagesIndex;
        private ProviderXml _provider;

        // progress bar values
        private double _progressBarValue;
        private int _min;
        private int _max = 10;
        private string _downloadingImageText;
        public bool IsDownloading { get; private set; }

        private readonly PostOption _postOption = new PostOption();
        private ObservableCollection<LogsListView> _processingLogs = new ObservableCollection<LogsListView>();

        public PostOptionViewModel()
        {
            LoggerInstance.AfterAppend += LoggerInstance_AfterAppend;

            LoggerInstance.AfterClear += delegate
                                             {
                                                 this.ProcessingLogs.Clear();
                                             };
        }

        private void LoggerInstance_AfterAppend(object sender, AfterAppendEventArgs e)
        {
            string imgName = String.Empty;
            switch (e.LogItem.Status)
            {
                case LogStatus.Info:
                    imgName = "face-smile.jpg";
                    break;
                case LogStatus.Warning:
                    imgName = "face-surprise.jpg";
                    break;
                case LogStatus.Error:
                    imgName = "face-sad.jpg";
                    break;
            }

            string imgSrc = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, imgName);
            this.ProcessingLogs.Add(new LogsListView { Txt = e.LogItem.Message, Image = imgSrc });
        }

        #region View Model properties
        public ObservableCollection<LogsListView> ProcessingLogs
        {
            get { return _processingLogs; }
            set { _processingLogs = value; }
        }

        public string WpFileName
        {
            get { return _wpFileName; }
            set 
            {
                if (_wpFileName != value)
                {
                    _wpFileName = value;
                    RaisePropertyChanged("WpFileName");
                }
            
            }
        }

        public string PostFolder
        {
            get { return _postOption.PostAppDataLocation; }
            set
            {
                if (_postOption.PostAppDataLocation != value)
                {
                    _postOption.PostAppDataLocation = value;
                    RaisePropertyChanged("PostFolder");
                }
            }
        }

        public string LocalImageFolder
        {
            get { return _postOption.LocalImageFolder; }
            set
            {
                if (_postOption.LocalImageFolder != value)
                {
                    _postOption.LocalImageFolder = value;
                    RaisePropertyChanged("LocalImageFolder");
                }
            }
        }

        public string RelImageFolder
        {
            get { return _postOption.RelImageFolder; }
            set
            {
                if (_postOption.RelImageFolder != value)
                {
                    _postOption.RelImageFolder = value;
                    RaisePropertyChanged("RelImageFolder");
                }
            }
        }

        public string BlogUrl
        {
            get { return _postOption.BlogUrl; }
            set
            {
                if (_postOption.BlogUrl != value)
                {
                    _postOption.BlogUrl = value;
                    RaisePropertyChanged("BlogUrl");
                }
            }
        }

        public string AuthorName
        {
            get { return _postOption.AuthorName; }
            set
            {
                if (_postOption.AuthorName != value)
                {
                    _postOption.AuthorName = value;
                    RaisePropertyChanged("AuthorName");
                }
            }
        }

        public bool DownloadImages
        {
            get { return _postOption.DownloadImages; }
            set
            {
                if (_postOption.DownloadImages != value)
                {
                    _postOption.DownloadImages = value;
                    RaisePropertyChanged("DownloadImages");
                }
            }
        }

        public bool IncludeDraft
        {
            get { return _postOption.IncludeDraft; }
            set
            {
                if (_postOption.IncludeDraft != value)
                {
                    _postOption.IncludeDraft = value;
                    RaisePropertyChanged("IncludeDraft");
                }
            }
        }

        public bool AddImgDropShadow
        {
            get { return _postOption.AddImgDropShadow; }
            set
            {
                if (_postOption.AddImgDropShadow != value)
                {
                    _postOption.AddImgDropShadow = value;
                    RaisePropertyChanged("AddImgDropShadow");
                }
            }
        }

        #endregion

        #region ICommand

        public ICommand OpenWpFile
        {
            get { return new RelayCommand(OpenWpFileExecute, () => !_saveButtonClicked); }
        }

        private void OpenWpFileExecute()
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Filter = "XML File (*.xml) | *.xml";
            fileDialog.CheckFileExists = true;

            if (fileDialog.ShowDialog() == true)
            {
                this.WpFileName = fileDialog.FileName;
            }
        }

        public ICommand OpenPostFolder
        {
            get { return new RelayCommand(OpenPostFolderExecute, () => !_saveButtonClicked);}
        }

        public void OpenPostFolderExecute()
        {
            FolderBrowserDialog browserDlg = new FolderBrowserDialog();
            if (browserDlg.ShowDialog() == DialogResult.OK)
            {
                this.PostFolder = browserDlg.SelectedPath;
            }
        }

        public ICommand OpenImageFolder
        {
            get { return new RelayCommand(OpenImageFolderExecute, delegate { return !_saveButtonClicked; }); }
        }

        private void OpenImageFolderExecute()
        {
            FolderBrowserDialog browserDlg = new FolderBrowserDialog();
            if (browserDlg.ShowDialog() == DialogResult.OK)
            {
                this.LocalImageFolder = browserDlg.SelectedPath;
            }
        }

        private void Clear()
        {
            LoggerInstance.Clear();
            this.ProgressBarValue = 0;
            _postImagesIndex = 1;
        }

        public ICommand Save
        {
            get { return new RelayCommand(SaveExecute, CanSave); }
        }

        private void SaveExecute()
        {
            this.Clear();
            this._saveButtonClicked = DownloadImages;
            this.IsDownloading = this.DownloadImages;

            _provider = new ProviderXml(_postOption);
            _provider.DownloadingImageEvent += provider_DownloadingImageEvent;
            _provider.DownloadingImageComplete += provider_DownloadingImageComplete;
                
            _provider.Parse(WpFileName);

            if (_provider.Post == null) return;

            try
            {
                _provider.Process();
                _postImagesTotalCount = _provider.Post.PostImages.Count * 2; // * 2 because img and href image
                this.Max = _postImagesTotalCount;
                _provider.Save();
            }
            catch (Exception ex)
            {
                LoggerInstance.Append(LogStatus.Error, "Error saving: {0}", ex.Message);
            }
        }

        private void provider_DownloadingImageEvent(object sender, DownloadingImagesArgs e)
        {
            this.DownloadingImageText = String.Format("Downloading images {0} from {1}: {2}",
                _postImagesIndex, _postImagesTotalCount, e.ImageName);

            this.ProgressBarValue = _postImagesTotalCount - (_postImagesTotalCount - _postImagesIndex);
            _postImagesIndex++;
        }

        private void provider_DownloadingImageComplete(object sender, DownloadingImagesArgs e)
        {
            this.IsDownloading = false;
            this._saveButtonClicked = false;
            
            switch (e.DownloadImagesStatus)
            {
                case DownloadImagesComplete.Successfully:
                    this.DownloadingImageText = "Downloading images completed.";
                    break;
                case DownloadImagesComplete.Canceled:
                    this.DownloadingImageText = "Downloading images canceled.";
                    break;
            }
        }

        private bool CanSave()
        {
            return !IsDownloading &&
                   !String.IsNullOrEmpty(this.WpFileName) &&
                   !String.IsNullOrEmpty(this.PostFolder) &&
                   !String.IsNullOrEmpty(this.LocalImageFolder) &&
                   !String.IsNullOrEmpty(this.BlogUrl) &&
                   !String.IsNullOrEmpty(this.AuthorName);
        }

        public ICommand CancelDownload
        {
            get { return new RelayCommand(CancelDownloadExecute, CanCancelDownload); }
        }

        private bool CanCancelDownload()
        {
            return this._saveButtonClicked;
        }

        private void CancelDownloadExecute()
        {
            IsDownloading = false;
            _provider.CancelDownloadImages();
        } 

        #endregion

        #region ProgressBar

        public double ProgressBarValue
        {
            get { return _progressBarValue; }
            set {
                if (_progressBarValue != value)
                {
                    _progressBarValue = value;
                    RaisePropertyChanged("ProgressBarValue");
                }
            }
        }

        public int Min
        {
            get { return _min; }
            set {
                if (_min != value)
                {
                    _min = value;
                    RaisePropertyChanged("Min");
                }
            }
        }

        public int Max
        {
            get { return _max; }
            set {
                if (_max != value)
                {
                    _max = value;
                    RaisePropertyChanged("Max");
                }
            }
        }

        public string DownloadingImageText
        {
            get { return _downloadingImageText; }
            set
            {
                if (_downloadingImageText != value)
                {
                    _downloadingImageText = value;
                    RaisePropertyChanged("DownloadingImageText");
                }
            }
        }

        #endregion

    }
}